package com.example.volunteer.service.impl;

import com.example.volunteer.config.FileStorageProperties;
import com.example.volunteer.exception.FileStorageException;
import com.example.volunteer.service.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@Service
public class FileStorageServiceImpl implements FileStorageService {

    private final Path fileStorageLocation;
    private final Path qrCodeStorageLocation;

    @Autowired
    public FileStorageServiceImpl(FileStorageProperties fileStorageProperties) {
        // 主文件存储位置
        this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
                .toAbsolutePath().normalize();

        // QR码专用存储位置
        this.qrCodeStorageLocation = Paths.get(fileStorageProperties.getUploadDir(), "qrcodes")
                .toAbsolutePath().normalize();

        try {
            Files.createDirectories(this.fileStorageLocation);
            Files.createDirectories(this.qrCodeStorageLocation);
        } catch (Exception ex) {
            throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
        }
    }

    @Override
    public String storeFile(byte[] fileBytes, String fileName) {
        return storeFileToLocation(fileBytes, fileName, this.fileStorageLocation);
    }

    @Override
    public byte[] loadFile(String fileName) {
        return loadFileFromLocation(fileName, this.fileStorageLocation);
    }

    @Override
    public void deleteFile(String fileName) {
        deleteFileFromLocation(fileName, this.fileStorageLocation);
    }

    @Override
    public String storeQRCode(byte[] qrCodeBytes, String fileName) {
        return storeFileToLocation(qrCodeBytes, fileName, this.qrCodeStorageLocation);
    }

    @Override
    public byte[] loadQRCode(String fileName) {
        return loadFileFromLocation(fileName, this.qrCodeStorageLocation);
    }

    private String storeFileToLocation(byte[] fileBytes, String fileName, Path location) {
        try {
            // 检查文件名是否包含非法字符
            if (fileName.contains("..")) {
                throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
            }

            // 解决文件名冲突问题
            String uniqueFileName = generateUniqueFileName(fileName);

            // 复制文件到目标位置
            Path targetLocation = location.resolve(uniqueFileName);
            Files.write(targetLocation, fileBytes);

            return uniqueFileName;
        } catch (IOException ex) {
            throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

    private byte[] loadFileFromLocation(String fileName, Path location) {
        try {
            Path filePath = location.resolve(fileName).normalize();
            return Files.readAllBytes(filePath);
        } catch (IOException ex) {
            throw new FileStorageException("File not found " + fileName, ex);
        }
    }

    private void deleteFileFromLocation(String fileName, Path location) {
        try {
            Path filePath = location.resolve(fileName).normalize();
            Files.deleteIfExists(filePath);
        } catch (IOException ex) {
            throw new FileStorageException("Could not delete file " + fileName, ex);
        }
    }

    private String generateUniqueFileName(String originalFileName) {
        String fileBaseName = originalFileName.substring(0, originalFileName.lastIndexOf('.'));
        String fileExtension = originalFileName.substring(originalFileName.lastIndexOf('.'));

        return fileBaseName + "_" + System.currentTimeMillis() + fileExtension;
    }
}